__author__ = 'Pierre Moermans'

from django.http import HttpResponse
from pyfacture import models
from pyfacture import message;

import datetime
import json
import logging
import uuid

logger = logging.getLogger(__name__)

class ClientDecoder(json.JSONDecoder):
    def decode(self, s):
        client_dict = json.loads(s)
        client = models.Client()
        client.name = client_dict['name']
        client.vat = client_dict['vat']
        address = models.Address()
        address.street = client_dict['street']
        address.zip = client_dict['zip']
        address.city = client_dict['city']
        address.country = client_dict['country']
        logger.debug("Decoded client " + str(client) + " with address " + str(address))
        return client,address

class AddressDecoder(json.JSONDecoder):
    def decode(self, s):
        address_dict = json.loads(s)
        address = models.Address()
        address.street = address_dict['street']
        address.zip = address_dict['zip']
        address.city = address_dict['city']
        address.country = address_dict['country']
        logger.debug("Decoded address " + str(address))
        return address;

def autocomplete(request):
    
    text = request.GET['term']

    clients = []
    try:
        clients = list(models.Client.objects.filter(name__icontains = text))
        logger.debug("Returned the following matching (with " + text + ") clients: " + str(clients))
    except Exception, e:
        logger.trace(e.message)
        logger.debug("No client has '" + text + "' in his name")


    json_response=[]
    for client in clients:
        address = getCurrentClientAddress(client)
        json_response.append(
            {
                'name': client.name,
                'street': address.street,
                'zip': address.zip,
                'city': address.city,
                'country': address.country,
                'vat': client.vat,
                'id': client.id
            }
        )

    return HttpResponse(json.dumps(json_response), mimetype='application/javascript')

def save(request):
    if not request.user.is_authenticated():
        logger.info("user requested to save a new client but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})
    
    if request.is_ajax():
        try:
            client,address = ClientDecoder().decode(request.raw_post_data)
            client.save()
            address.save()
            client_address_link = models.ClientAddressLink()
            client_address_link.client = client
            client_address_link.address = address
            client_address_link.since = datetime.date.today()
            client_address_link.save()
            logger.info("Saved client " + str(client) + " with address " + str(address));
        except Exception, e:
            uid = uuid.uuid4()
            logger.error(message.msgWithUUID(uid, "Error saving client " + client.name), e)
            return message.buildError("Error saving client", uid)

        response = {}
        response['id'] = client.id
        response['name'] = client.name
        response['vat'] = client.vat
        response['street'] = address.street
        response['zip'] = address.zip
        response['city'] = address.city
        response['country'] = address.country

        return HttpResponse(json.dumps(response), 'application/json')

def getCurrentClientAddress(client):
    current_address_link = models.ClientAddressLink.objects.filter(client=client).latest('since')
    logger.debug("Retrieved current address of client " + client.name + ": " + str(current_address_link.address))
    return current_address_link.address

def saveAddress(request, client_id):
    if not request.user.is_authenticated():
        logger.info("user requested to save a new address for client " + str(client_id) + " but is not authenticated")
        return render_to_response('logon.html', {'original_url': request.path})

    if request.is_ajax():
        try:
            client = models.Client.objects.get(id=client_id)
        except models.Client.DoesNotExist:
            logger.warn("User " + request.user.id + " asked to save a new address for client with id " + client_id + " but the client does not exist")
            return message.buildError("The client doesn't exist")
        
        try:
            address = AddressDecoder().decode(request.raw_post_data)
            address.save()
            client_address_link = models.ClientAddressLink()
            client_address_link.client = client
            client_address_link.address = address
            client_address_link.since = datetime.date.today()
            client_address_link.save()

            response = {}
            response['street'] = address.street
            response['zip'] = address.zip
            response['city'] = address.city
            response['country'] = address.country
            return HttpResponse(json.dumps(response), 'application/json')
        except Exception, e:
            uid = uuid.uuid4()
            logger.error(message.msgWithUUID(uid, "Error saving new address for client " + client.name), e)
            return message.buildError("Error saving new address", uid)
